#include "fonttextviewmainwindow.h"
#include "qdebug.h"
#include "ui_fonttextviewmainwindow.h"

#include "constants/fontdeclare.h"

#include <QDragEnterEvent>
#include <QFileDialog>
#include <QFileInfo>
#include <QMimeData>

FontTextViewMainWindow::FontTextViewMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::FontTextViewMainWindow)
{
    ui->setupUi(this);
    ui->textEdit->setText(test_source_code());

    //
    connect(ui->comboBox, &QComboBox::currentTextChanged, this, [this](const QString &text){
        ui->statusbar->showMessage("当前设置字体为:" + text);
        // 对加载过的字体获取字体家族名称
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(ui->comboBox->currentData().toInt());
        ui->fontFamiliesComboBox->clear();
        ui->fontFamiliesComboBox->addItems(fontFamilies);
        //
        if (fontFamilies.isEmpty()) {
            return;
        }

        ui->fontComboBox->setCurrentText(fontFamilies.at(0));

//        QFont newFont;
//        newFont.setFamilies(fontFamilies);
//        ui->textEdit->setFont(newFont);
    });

//    connect(ui->fontFamiliesComboBox, &QComboBox::currentTextChanged)

    QStringList fontFiles;

    // [1]
    // fontFiles << source_code_pro_font_files();
    // fontFiles << fira_code_font_files();

    // [2] 使用
    fontFiles << fira_code_fonts;
    fontFiles << source_code_pro_fonts;
    fontFiles << cascadia_mono_fonts;
    fontFiles << jetbrains_mono_fonts;
    for (const QString &fontFile : fontFiles) {
        int fontId = QFontDatabase::addApplicationFont(fontFile);
        if (fontId == -1) {
            qWarning() << "Failed to load font:" << fontFile;
        } else {
            ui->comboBox->addItem(QFileInfo(fontFile).fileName(), fontId);
            qInfo() << "load font:" << fontId << fontFile;
        }
    }

    connect(ui->bold, SIGNAL(stateChanged(int)), this, SLOT(stateChanged()));
    connect(ui->italic, SIGNAL(stateChanged(int)), this, SLOT(stateChanged()));
    connect(ui->overline, SIGNAL(stateChanged(int)), this, SLOT(stateChanged()));


    action_import_fonts = ui->menu->addAction("字体导入", this, [this](){
        QStringList fontFiles = QFileDialog::getOpenFileNames(nullptr, "选择字体文件", "", "*.ttf");
        if (!fontFiles.isEmpty()) {
            load_font_files(fontFiles);
        }
    });
}

FontTextViewMainWindow::~FontTextViewMainWindow()
{
    delete ui;
}

void FontTextViewMainWindow::load_font_files(QStringList fontFiles)
{
    for (const QString &fontFile : fontFiles) {
        int fontId = QFontDatabase::addApplicationFont(fontFile);
        if (fontId == -1) {
            qWarning() << "Failed to load font:" << fontFile;
        } else {
            ui->comboBox->addItem(QFileInfo(fontFile).fileName(), fontId);
            qInfo() << "load font:" << fontId << fontFile;
        }
    }
}

void FontTextViewMainWindow::on_fontComboBox_currentFontChanged(const QFont &f)
{
    ui->textEdit->setFont(f);

    ui->bold->setChecked(f.bold());
    ui->defaultFamily->setText(f.defaultFamily());
    ui->family->setText(f.family());
    ui->families->setText(f.families().join(","));
    ui->weight->setValue(f.weight());
    ui->italic->setChecked(f.italic());
    ui->overline->setChecked(f.overline());
}

void FontTextViewMainWindow::stateChanged()
{
    QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
    auto x = ui->textEdit->font();
    if (checkBox == ui->bold) x.setBold(checkBox->isChecked());
    if (checkBox == ui->italic) x.setItalic(checkBox->isChecked());
    if (checkBox == ui->overline) x.setOverline(checkBox->isChecked());
    ui->textEdit->setFont(x);
}

QString FontTextViewMainWindow::test_source_code()
{
    return (R"(
/**
 * DOC: Xe Device Block Diagram
 *
 * The diagram below represents a high-level simplification of a discrete
 * GPU supported by the Xe driver. It shows some device components which
 * are necessary to understand this API, as well as how their relations
 * to each other. This diagram does not represent real hardware::
 *
 *   ┌──────────────────────────────────────────────────────────────────┐
 *   │ ┌──────────────────────────────────────────────────┐ ┌─────────┐ │
 *   │ │        ┌───────────────────────┐   ┌─────┐       │ │ ┌─────┐ │ │
 *   │ │        │         VRAM0         ├───┤ ... │       │ │ │VRAM1│ │ │
 *   │ │        └───────────┬───────────┘   └─GT1─┘       │ │ └──┬──┘ │ │
 *   │ │ ┌──────────────────┴───────────────────────────┐ │ │ ┌──┴──┐ │ │
 *   │ │ │ ┌─────────────────────┐  ┌─────────────────┐ │ │ │ │     │ │ │
 *   │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │  │ ┌─────┐ ┌─────┐ │ │ │ │ │     │ │ │
 *   │ │ │ │ │EU│ │EU│ │EU│ │EU│ │  │ │RCS0 │ │BCS0 │ │ │ │ │ │     │ │ │
 *   │ │ │ │ └──┘ └──┘ └──┘ └──┘ │  │ └─────┘ └─────┘ │ │ │ │ │     │ │ │
 *   │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │  │ ┌─────┐ ┌─────┐ │ │ │ │ │     │ │ │
 *   │ │ │ │ │EU│ │EU│ │EU│ │EU│ │  │ │VCS0 │ │VCS1 │ │ │ │ │ │     │ │ │
 *   │ │ │ │ └──┘ └──┘ └──┘ └──┘ │  │ └─────┘ └─────┘ │ │ │ │ │     │ │ │
 *   │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │  │ ┌─────┐ ┌─────┐ │ │ │ │ │     │ │ │
 *   │ │ │ │ │EU│ │EU│ │EU│ │EU│ │  │ │VECS0│ │VECS1│ │ │ │ │ │ ... │ │ │
 *   │ │ │ │ └──┘ └──┘ └──┘ └──┘ │  │ └─────┘ └─────┘ │ │ │ │ │     │ │ │
 *   │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │  │ ┌─────┐ ┌─────┐ │ │ │ │ │     │ │ │
 *   │ │ │ │ │EU│ │EU│ │EU│ │EU│ │  │ │CCS0 │ │CCS1 │ │ │ │ │ │     │ │ │
 *   │ │ │ │ └──┘ └──┘ └──┘ └──┘ │  │ └─────┘ └─────┘ │ │ │ │ │     │ │ │
 *   │ │ │ └─────────DSS─────────┘  │ ┌─────┐ ┌─────┐ │ │ │ │ │     │ │ │
 *   │ │ │                          │ │CCS2 │ │CCS3 │ │ │ │ │ │     │ │ │
 *   │ │ │ ┌─────┐ ┌─────┐ ┌─────┐  │ └─────┘ └─────┘ │ │ │ │ │     │ │ │
 *   │ │ │ │ ... │ │ ... │ │ ... │  │                 │ │ │ │ │     │ │ │
 *   │ │ │ └─DSS─┘ └─DSS─┘ └─DSS─┘  └─────Engines─────┘ │ │ │ │     │ │ │
 *   │ │ └───────────────────────────GT0────────────────┘ │ │ └─GT2─┘ │ │
 *   │ └────────────────────────────Tile0─────────────────┘ └─ Tile1──┘ │
 *   └─────────────────────────────Device0───────┬──────────────────────┘
 *                                               │
 *                        ───────────────────────┴────────── PCI bus
 */
)");
}

QStringList FontTextViewMainWindow::source_code_pro_font_files()
{
    QString fonts = R"(
      static/SourceCodePro-ExtraLight.ttf
      static/SourceCodePro-Light.ttf
      static/SourceCodePro-Regular.ttf
      static/SourceCodePro-Medium.ttf
      static/SourceCodePro-SemiBold.ttf
      static/SourceCodePro-Bold.ttf
      static/SourceCodePro-ExtraBold.ttf
      static/SourceCodePro-Black.ttf
      static/SourceCodePro-ExtraLightItalic.ttf
      static/SourceCodePro-LightItalic.ttf
      static/SourceCodePro-Italic.ttf
      static/SourceCodePro-MediumItalic.ttf
      static/SourceCodePro-SemiBoldItalic.ttf
      static/SourceCodePro-BoldItalic.ttf
      static/SourceCodePro-ExtraBoldItalic.ttf
      static/SourceCodePro-BlackItalic.ttf
    )";

    QString prefix = "";
#ifdef DEBUG_FONT_DIR
    prefix = DEBUG_FONT_DIR "/SourceCodePro";
#endif

    if (prefix.isEmpty()) {
        return QStringList();
    }

    QStringList files;

    qDebug() << "load font:";
    foreach (auto var, fonts.split(QRegExp("\\s+"), Qt::SkipEmptyParts)) {
        qDebug() << "   -" << var;
        files << prefix + "/" + var;
    }

    return files;
}

QStringList FontTextViewMainWindow::fira_code_font_files()
{
    QString fonts = R"(
      Fira_Code/static/FiraCode-Light.ttf
      Fira_Code/static/FiraCode-Regular.ttf
      Fira_Code/static/FiraCode-Medium.ttf
      Fira_Code/static/FiraCode-SemiBold.ttf
      Fira_Code/static/FiraCode-Bold.ttf
    )";

    QString prefix = "";
#ifdef DEBUG_FONT_DIR
    prefix = DEBUG_FONT_DIR;
#endif

    if (prefix.isEmpty()) {
        return QStringList();
    }

    QStringList files;

    qDebug() << "load font:";
    foreach (auto var, fonts.split(QRegExp("\\s+"), Qt::SkipEmptyParts)) {
        qDebug() << "   -" << var;
        files << prefix + "/" + var;
    }

    return files;
}

QStringList FontTextViewMainWindow::cascadia_mono_font_files()
{
    return {};
}

QStringList FontTextViewMainWindow::jetbrains_mono_font_files()
{
    QString fonts = R"(
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Bold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-BoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-ExtraBold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-ExtraBoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-ExtraLight.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-ExtraLightItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Italic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Light.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-LightItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Medium.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-MediumItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Regular.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-SemiBold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-SemiBoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-Thin.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMono-ThinItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Bold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-BoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-ExtraBold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-ExtraLight.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Italic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Light.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-LightItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Medium.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-MediumItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Regular.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-SemiBold.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-Thin.ttf
      JetBrainsMono-2.304/fonts/ttf/JetBrainsMonoNL-ThinItalic.ttf
    )";

    QString prefix = "";
#ifdef DEBUG_FONT_DIR
    prefix = DEBUG_FONT_DIR;
#endif

    if (prefix.isEmpty()) {
        return QStringList();
    }

    QStringList files;

    qDebug() << "load font:";
    foreach (auto var, fonts.split(QRegExp("\\s+"), Qt::SkipEmptyParts)) {
        qDebug() << "   -" << var;
        files << prefix + "/" + var;
    }

    return files;
}

void FontTextViewMainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    const QMimeData *mimeData = event->mimeData();
    if (mimeData->hasUrls() && mimeData->urls().at(0).isLocalFile()) {
        if (mimeData->urls().at(0).toLocalFile().endsWith(".ttf")) {
            event->accept();
        }
    }
}

void FontTextViewMainWindow::dropEvent(QDropEvent *event)
{
    const QMimeData *mimeData = event->mimeData();

    QStringList fontFiles;
    foreach (auto var, mimeData->urls()) {
        QString filePath = var.toLocalFile();
        if (filePath.endsWith(".ttf")) {
            fontFiles << var.toLocalFile();
        }
    }
    load_font_files(fontFiles);
}
